#ifndef __USERLOGINSECTION2_H__
#define __USERLOGINSECTION2_H__

#include "TcpConnection.h"
#include "Logger.h"
#include "Packet.h"
#include "TLV.h"
#include "YesCrypt.h"
#include"MySQLClient.h"
#include <string.h>

using namespace myNameSpace;

/* void hexDump(const char* data, int size) { */
/*     for (int i = 0; i < size; i++) { */
/*         printf("%02X ", (unsigned char)data[i]); */
/*         if ((i + 1) % 16 == 0) printf("\n"); */
/*     } */
/*     printf("\n"); */
/* } */

class UserLoginSection2 {
public:
    UserLoginSection2(const Packet &packet, shared_ptr<TcpConnection> pTcpConnection, MySQLClient &mysqlClient): _packet(packet), _pTcpConnection(pTcpConnection), _mysqlClient(mysqlClient) {}

    void process() {
        moqi::LOG_INFO("Thread %u: UserLoginSection2.", pthread_self());
        /* hexDump(_packet._msg.c_str(), _packet._msg.size()); */
        const char *msg = _packet._msg.c_str();
        // 1. 解析用户名、密文
        const char *p = msg;
        int userNameLength = 0;
        memcpy(&userNameLength, p, sizeof(int)); // userName长度
        p += sizeof(int);
        char userName[100] = {0};
        memcpy(userName, p, userNameLength); // userName
        p += userNameLength;
        printf("userName: %s, userNameLength: %d\n", userName, userNameLength);
        int encrytedPasswordLength = 0;
        memcpy(&encrytedPasswordLength, p, sizeof(int)); // encrytedPassword长度
        p += sizeof(int);
        char encrytedPassword[1024] = {0};
        memcpy(encrytedPassword, p, encrytedPasswordLength); // encrytedPassword
        printf("encrytedPassword: %s, encrytedPasswordLength: %d\n", encrytedPassword, encrytedPasswordLength);
        // 2.1 若该用户名在数据库中不存在，返回error报文
        TLV response;
        if (!_mysqlClient.isExist("monitor_client", "client_name", userName)) {
            char buf[160] = {0};
            sprintf(buf, "User %s doesn't exist.", userName);
            moqi::LOG_WARN(buf);
            response._type = TASK_LOGIN_SECTION2_RESP_ERROR;
            response._length = strlen(buf);
            strcpy(response._data, buf);
            _pTcpConnection->sendInLoop(response);
            return;
        }
        // 2.2 若该用户名在数据库中存在，从数据库中获取该用户名对应的密文
        string encrytedString = _mysqlClient.findData("monitor_client", "client_encrypt", "client_name", userName);
        // 3.1 若密文为空，返回error报文
        if (encrytedString.empty()) {
            const char *buf = "Get encryptPassword from database failed.";
            moqi::LOG_ERROR(buf);
            response._type = TASK_LOGIN_SECTION2_RESP_ERROR;
            response._length = strlen(buf);
            strcpy(response._data, buf);
            _pTcpConnection->sendInLoop(response);
            return;
        }
        // 3.2 若密文不为空，但和客户端发送的密文不一致，返回error报文
        if (encrytedString != encrytedPassword) {
            const char *buf = "Password error.";
            moqi::LOG_WARN(buf);
            response._type = TASK_LOGIN_SECTION2_RESP_ERROR;
            response._length = strlen(buf);
            strcpy(response._data, buf);
            _pTcpConnection->sendInLoop(response);
            return;
        }
        // 3.3 若密文不为空且和客户端发送的密文一致，从数据库中取出该用户的id
        string res = _mysqlClient.findData("monitor_client", "client_id", "client_name", userName);
        // 4.1 若id不存在，返回error报文
        if (res.empty()) {
            const char *buf = "Get client id from database failed.";
            moqi::LOG_ERROR(buf);
            response._type = TASK_LOGIN_SECTION2_RESP_ERROR;
            response._length = strlen(buf);
            strcpy(response._data, buf);
        }
        // 4.2 若id存在，将id返回给客户端
        else {
            int id = std::stoi(res);
            response._type = TASK_LOGIN_SECTION2_RESP_OK;
            response._length = sizeof(int);
            memcpy(response._data, &id, sizeof(int));
        }
        _pTcpConnection->sendInLoop(response);
    }

private:
    Packet _packet;
    shared_ptr<TcpConnection> _pTcpConnection;
    MySQLClient &_mysqlClient;
};

#endif
